<template>
  <div class="base-table">
    <!-- 表格头部 -->
    <div v-if="showHeader" class="base-table__header">
      <slot name="header">
        <div class="base-table__title">{{ title }}</div>
        <div class="base-table__actions">
          <slot name="actions" />
        </div>
      </slot>
    </div>

    <!-- 表格内容 -->
    <div class="base-table__content">
      <van-list
        v-model:loading="loading"
        :finished="finished"
        :error="error"
        :immediate-check="immediateCheck"
        :offset="offset"
        finished-text="没有更多了"
        error-text="请求失败，点击重新加载"
        @load="handleLoad"
      >
        <!-- 表格项 -->
        <div
          v-for="(item, index) in data"
          :key="getRowKey(item, index)"
          :class="getRowClass(item, index)"
          @click="handleRowClick(item, index)"
        >
          <slot :item="item" :index="index">
            <!-- 默认表格项布局 -->
            <div class="base-table__row">
              <div
                v-for="column in visibleColumns"
                :key="column.key"
                :class="getCellClass(column)"
                :style="getCellStyle(column)"
              >
                <!-- 自定义列内容 -->
                <template v-if="column.slot">
                  <slot :name="column.slot" :item="item" :value="getCellValue(item, column)" :column="column" :index="index" />
                </template>
                <!-- 默认列内容 -->
                <template v-else>
                  <div class="base-table__cell-content">
                    <span v-if="column.label" class="base-table__cell-label">{{ column.label }}:</span>
                    <span class="base-table__cell-value">{{ formatCellValue(item, column) }}</span>
                  </div>
                </template>
              </div>
            </div>
          </slot>
        </div>

        <!-- 空状态 -->
        <div v-if="!loading && data.length === 0" class="base-table__empty">
          <slot name="empty">
            <van-empty :description="emptyText" />
          </slot>
        </div>
      </van-list>
    </div>

    <!-- 表格底部 -->
    <div v-if="showFooter" class="base-table__footer">
      <slot name="footer" />
    </div>
  </div>
</template>

<script>
import { ref, computed, defineComponent } from 'vue'
import { formatDateTime, formatMoney, formatPhone } from '@/utils/formatData'

export default defineComponent({
  name: 'BaseTable',
  props: {
    /**
     * 表格数据
     */
    data: {
      type: Array,
      default: () => []
    },
    /**
     * 表格列配置
     */
    columns: {
      type: Array,
      default: () => []
    },
    /**
     * 表格标题
     */
    title: {
      type: String,
      default: ''
    },
    /**
     * 是否显示头部
     */
    showHeader: {
      type: Boolean,
      default: true
    },
    /**
     * 是否显示底部
     */
    showFooter: {
      type: Boolean,
      default: false
    },
    /**
     * 行键字段
     */
    rowKey: {
      type: [String, Function],
      default: 'id'
    },
    /**
     * 是否加载中
     */
    loading: {
      type: Boolean,
      default: false
    },
    /**
     * 是否加载完成
     */
    finished: {
      type: Boolean,
      default: false
    },
    /**
     * 是否加载错误
     */
    error: {
      type: Boolean,
      default: false
    },
    /**
     * 是否立即检查
     */
    immediateCheck: {
      type: Boolean,
      default: true
    },
    /**
     * 滚动条与底部距离小于 offset 时触发加载
     */
    offset: {
      type: Number,
      default: 300
    },
    /**
     * 空状态文本
     */
    emptyText: {
      type: String,
      default: '暂无数据'
    },
    /**
     * 是否可点击行
     */
    clickable: {
      type: Boolean,
      default: false
    },
    /**
     * 表格布局模式
     */
    layout: {
      type: String,
      default: 'card',
      validator: (value) => ['card', 'list', 'grid'].includes(value)
    }
  },
  emits: ['load', 'row-click', 'cell-click'],
  setup(props, { emit }) {
    /**
     * 可见列
     */
    const visibleColumns = computed(() => {
      return props.columns.filter(column => column.visible !== false)
    })

    /**
     * 获取行键
     */
    const getRowKey = (item, index) => {
      if (typeof props.rowKey === 'function') {
        return props.rowKey(item, index)
      }
      return item[props.rowKey] || index
    }

    /**
     * 获取行样式类
     */
    const getRowClass = (item, index) => {
      const classes = ['base-table__item']
      
      classes.push(`base-table__item--${props.layout}`)
      
      if (props.clickable) {
        classes.push('base-table__item--clickable')
      }
      
      return classes
    }

    /**
     * 获取单元格样式类
     */
    const getCellClass = (column) => {
      const classes = ['base-table__cell']
      
      if (column.align) {
        classes.push(`base-table__cell--${column.align}`)
      }
      
      if (column.className) {
        classes.push(column.className)
      }
      
      return classes
    }

    /**
     * 获取单元格样式
     */
    const getCellStyle = (column) => {
      const style = {}
      
      if (column.width) {
        style.width = typeof column.width === 'number' ? `${column.width}px` : column.width
      }
      
      if (column.minWidth) {
        style.minWidth = typeof column.minWidth === 'number' ? `${column.minWidth}px` : column.minWidth
      }
      
      return style
    }

    /**
     * 获取单元格值
     */
    const getCellValue = (item, column) => {
      if (column.key) {
        return item[column.key]
      }
      return ''
    }

    /**
     * 格式化单元格值
     */
    const formatCellValue = (item, column) => {
      const value = getCellValue(item, column)
      
      if (column.formatter) {
        return column.formatter(value, item, column)
      }
      
      // 根据类型自动格式化
      switch (column.type) {
        case 'date':
          return formatDateTime(value, 'YYYY-MM-DD')
        case 'datetime':
          return formatDateTime(value)
        case 'money':
          return formatMoney(value)
        case 'phone':
          return formatPhone(value)
        default:
          return value || '--'
      }
    }

    /**
     * 加载事件处理
     */
    const handleLoad = () => {
      emit('load')
    }

    /**
     * 行点击事件处理
     */
    const handleRowClick = (item, index) => {
      if (props.clickable) {
        emit('row-click', item, index)
      }
    }

    /**
     * 单元格点击事件处理
     */
    const handleCellClick = (item, column, index) => {
      emit('cell-click', item, column, index)
    }

    return {
      visibleColumns,
      getRowKey,
      getRowClass,
      getCellClass,
      getCellStyle,
      getCellValue,
      formatCellValue,
      handleLoad,
      handleRowClick,
      handleCellClick
    }
  }
})
</script>

<style lang="scss" scoped>
.base-table {
  background-color: #fff;

  &__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 16px;
    border-bottom: 1px solid #ebedf0;
  }

  &__title {
    font-size: 16px;
    font-weight: 500;
    color: #323233;
  }

  &__actions {
    display: flex;
    align-items: center;
    gap: 8px;
  }

  &__content {
    min-height: 200px;
  }

  &__item {
    border-bottom: 1px solid #f7f8fa;

    &:last-child {
      border-bottom: none;
    }

    &--clickable {
      cursor: pointer;
      transition: background-color 0.2s;

      &:hover {
        background-color: #f7f8fa;
      }

      &:active {
        background-color: #ebedf0;
      }
    }

    // 卡片布局
    &--card {
      padding: 16px;

      .base-table__row {
        display: flex;
        flex-direction: column;
        gap: 8px;
      }

      .base-table__cell {
        display: flex;
        align-items: center;
      }

      .base-table__cell-content {
        display: flex;
        align-items: center;
        width: 100%;
      }

      .base-table__cell-label {
        min-width: 80px;
        font-size: 14px;
        color: #969799;
      }

      .base-table__cell-value {
        flex: 1;
        font-size: 14px;
        color: #323233;
      }
    }

    // 列表布局
    &--list {
      padding: 12px 16px;

      .base-table__row {
        display: flex;
        align-items: center;
        gap: 12px;
      }

      .base-table__cell {
        flex: 1;
        min-width: 0;
      }

      .base-table__cell-content {
        display: flex;
        flex-direction: column;
        gap: 4px;
      }

      .base-table__cell-label {
        font-size: 12px;
        color: #969799;
      }

      .base-table__cell-value {
        font-size: 14px;
        color: #323233;
      }
    }

    // 网格布局
    &--grid {
      padding: 16px;

      .base-table__row {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
        gap: 16px;
      }

      .base-table__cell {
        display: flex;
        flex-direction: column;
        align-items: center;
        text-align: center;
      }

      .base-table__cell-label {
        font-size: 12px;
        color: #969799;
        margin-bottom: 4px;
      }

      .base-table__cell-value {
        font-size: 14px;
        color: #323233;
      }
    }
  }

  &__cell {
    &--left {
      text-align: left;
    }

    &--center {
      text-align: center;
    }

    &--right {
      text-align: right;
    }
  }

  &__empty {
    padding: 32px 16px;
    text-align: center;
  }

  &__footer {
    padding: 16px;
    border-top: 1px solid #ebedf0;
    background-color: #f7f8fa;
  }
}
</style>